package org.xiaov.codeautocreator.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.xiaov.codeautocreator.common.R;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 描述：处理全局异常
 * </p>
 *
 * @author xiaovcloud
 * @since 2021/9/5 18:32
 */
@ControllerAdvice
@Slf4j
public class CodeAutoBizExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public R defaultErrorHandler(HttpServletRequest req, Exception e) {
        //404资源直接不打印，直接返回
        if (e instanceof NoHandlerFoundException) {
            return R.failMsg("请求路径未找到");
        }

        log.error("<<<===访问CodeAuto出错，开始输出日志===>>>");
        log.error("请求类型：{}，访问的路径：{}", req.getMethod(), req.getRequestURL());
        StringBuilder builder = new StringBuilder("#");
        Map<String, String[]> parameterMap = req.getParameterMap();
        parameterMap.forEach((k, v) -> {
            builder.append(k).append(":").append(Arrays.toString(v)).append("#");
        });
        log.error("访问的参数：[{}]", builder);
        R result = null;
        //自己的业务逻辑错误
        if (e instanceof CodeAutoBizException) {
            result = R.failMsg(e.getMessage());
        }
        //参数校验的问题
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException eb = (MethodArgumentNotValidException) e;
            String message = Objects.requireNonNull(eb.getBindingResult().getFieldError()).getDefaultMessage();
            result = R.failMsg(message);
        }
        //如果前面没有匹配到，则匹配通用的500错误
        if (result == null) {
            result = R.failMsg("[服务器内部错误]: " + e.getMessage());
        }
        log.error("<<<===异常信息栈开始打印===>>>");
        e.printStackTrace();
        return result;
    }

}
